<?php


namespace App\Http\Requests;


use App\Exceptions\FormException;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;

class BaseRequest extends FormRequest
{
    /**
     * 验证场景
     * @var array
     */
    protected $scenes = [];

    /**
     * 当前验证场景
     * @var
     */
    protected $currentScene;

    /**
     * 验证规则
     * @var
     */
    protected $rules;


    /**
     * 是否自动验证
     * @var bool
     */
    private $autoValidate = false;


    /**
     * 设置验证场景
     * @param $scene
     * @return $this
     */
    public function scene($scene)
    {
        $this->currentScene = $this->scenes[$scene];
        $rules = $this->container->call([$this, 'rules']);
        $this->rules = array_intersect_key($rules, array_flip($this->currentScene));
        return $this;
    }

    /**
     * 处理验证
     * @return array|void
     * @throws \Illuminate\Validation\ValidationException
     */
    public function validate()
    {
        $this->handleValidate();
    }


    /**
     * 覆写验证器
     * @param ValidationFactory $factory
     * @return Validator
     */
    protected function createDefaultValidator(ValidationFactory $factory)
    {
        if (empty($this->rules)) {
            $this->rules = $this->container->call([$this, 'rules']);
        }
        return $factory->make(
            $this->validationData(), $this->rules,
            $this->messages(), $this->attributes()
        );
    }


    /**
     * 覆写自动验证方法
     */
    public function validateResolved()
    {
        if ($this->autoValidate) {
            $this->handleValidate();
        }
    }


    /**
     * 处理验证
     * @throws \Illuminate\Validation\ValidationException
     */
    protected function handleValidate()
    {
        $instance = $this->getValidatorInstance();
        if ($instance->fails()) {
            $this->failedValidation($instance);
        }
        $this->passedValidation();
    }


    /**
     * 验证失败抛出异常
     * @param Validator $validator
     * @throws FormException
     */
    protected function failedValidation(Validator $validator)
    {
        throw new FormException($validator->errors()->first(),-1);
    }

}
